﻿using System;
using System.Linq;
using System.Windows;
using System.Collections.Generic;

namespace RSSReader.MobileClient.Model
{
    public class AsyncDataManager
    {
        // This dictionary will help handle waiting for asynchronous data callbacks.
        private Dictionary<string, int[]> m_ExpectedData;
        private Action m_FinalProcess;
        private object m_Locker = new object();
        public AsyncDataManager(Action _finalProcess)
        {
            m_ExpectedData = new Dictionary<string, int[]>();
            m_FinalProcess = _finalProcess;
        }

        public void SetExpectation(string _key, int _occurrances = 1)
        {
            m_ExpectedData[_key] = new[] { _occurrances, 0 };
        }

        public void ManageCallbacks(string _key, Action _action = null)
        {
            lock (m_Locker)
            {
                m_ExpectedData[_key][1]++;
                if (_action != null)
                {
                    _action();
                }
                // Once all the expected callbacks have been handled, using a 
                // Dispatcher gets us back onto the UI thread and out of the scope of the lock.
                if (!m_ExpectedData.Values.Any(v => v[0] != v[1]))
                {
                    Deployment.Current.Dispatcher.BeginInvoke(m_FinalProcess);
                }
            }
        }

        // Without requiring that all expected async calls are complete, we can check for a certain set.
        public bool TestForSubsetComplete(params string[] _items)
        {
            return (!m_ExpectedData.Keys.ToList()
                .Where(k => _items.Contains(k))
                .Any(v => m_ExpectedData[v][0] != m_ExpectedData[v][1]));
        }
    }

}